package com.server.common.logistics.jc;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.server.common.code.utils.GsonUtils;
import com.server.common.logistics.base.BaseLogisticsService;
import com.server.common.logistics.enums.LogisticsCompanyEnum;
import com.server.common.logistics.jc.create.JCCreateOrderRequest;
import com.server.common.logistics.jc.create.JCCreateOrderResponse;
import com.server.common.logistics.jc.enums.JCApiEnum;
import com.server.common.logistics.jc.printLabel.JCPrintLabelRequest;
import com.server.common.logistics.jc.track.JCGetTrackRequest;
import com.server.common.logistics.jc.track.JCGetTrackResponse;
import com.server.common.logistics.request.LogisticsRequest;
import com.server.common.logistics.result.CreateOrderResult;
import com.server.common.logistics.result.GetTrackResult;
import com.server.common.logistics.result.HoldOrderResult;
import com.server.common.logistics.result.PrintLabelSyncResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class JCServiceImpl extends BaseLogisticsService {

    @Resource
    private JCConfig jcConfig;

    @Override
    public CreateOrderResult createOrder(LogisticsRequest orderRequest) {
        CreateOrderResult createOrderResult = new CreateOrderResult();

        try {
            if(!(orderRequest instanceof JCCreateOrderRequest)){
                createOrderResult.setErrorMsg("创建物流订单参数有误");
                return createOrderResult;
            }
            
            JCCreateOrderRequest jcCreateOrderRequest = (JCCreateOrderRequest) orderRequest;

            HttpRequest post = HttpUtil.createPost(jcConfig.getApiUrl() + JCApiEnum.CREATE_ORDER.getApiPath());
            jcCreateOrderRequest.setCustomerId(String.valueOf(jcConfig.getCustomerId()));
            jcCreateOrderRequest.setCustomerUserid(String.valueOf(jcConfig.getCustomerUserId()));
            post.form("param", GsonUtils.getGson().toJson(jcCreateOrderRequest));

            String body = post.execute().body();

            if(ObjectUtils.isEmpty(body)){
                createOrderResult.setErrorMsg("创建物流订单失败");
                return createOrderResult;
            }

            String decode = URLUtil.decode(body);

            log.info("佳成物流创建单接口:"+decode);

            JCCreateOrderResponse jcCreateOrderResponse = GsonUtils.getGson().fromJson(decode, JCCreateOrderResponse.class);

            if(!jcCreateOrderResponse.responseOk()){
                createOrderResult.setErrorMsg(jcCreateOrderResponse.getMessage());
                return createOrderResult;
            }

            if(jcCreateOrderResponse.dataEmpty()){
                createOrderResult.setErrorMsg("创建物流订单失败");
                return createOrderResult;
            }

            createOrderResult.setTrackingNumber(jcCreateOrderResponse.getTrackingNumber());
            createOrderResult.setThirdOrderId(jcCreateOrderResponse.getOrderId());

        }catch (Exception e){
            log.error("创建物流订单失败",e);
            createOrderResult.setErrorMsg("创建物流订单失败");
        }
        return createOrderResult;
    }

    @Override
    public GetTrackResult getTracking(LogisticsRequest getTrackRequest) {
        GetTrackResult getTrackResult = new GetTrackResult();

        try {
            if(!(getTrackRequest instanceof JCGetTrackRequest)){
                getTrackResult.setErrorMsg("获取物流轨迹参数有误");
                return getTrackResult;
            }

            JCGetTrackRequest jcGetTrackRequest = (JCGetTrackRequest) getTrackRequest;

            HttpRequest httpRequest = HttpUtil.createGet(jcConfig.getApiUrl() + JCApiEnum.GET_TRACK.getApiPath() + jcGetTrackRequest.getTrackingNumber());
            String body = httpRequest.execute().body();

            if(ObjectUtils.isEmpty(body)){
                getTrackResult.setErrorMsg("获取物流轨迹失败");
                return getTrackResult;
            }

            List<JCGetTrackResponse> jcGetTrackResponseList = JSONUtil.toList(body, JCGetTrackResponse.class);
            if(ObjectUtils.isEmpty(jcGetTrackResponseList)){
                getTrackResult.setErrorMsg("获取物流轨迹失败");
                return getTrackResult;
            }
            JCGetTrackResponse jcGetTrackResponse = CollUtil.getFirst(jcGetTrackResponseList);

            if(!jcGetTrackResponse.responseOk()) {
                getTrackResult.setErrorMsg("获取物流轨迹失败");
                return getTrackResult;
            }

            if(jcGetTrackResponse.dataEmpty()) {
                getTrackResult.setErrorMsg("获取物流轨迹失败");
                return getTrackResult;
            }
            List<JCGetTrackResponse.Data> trackResponseDataList = jcGetTrackResponse.getData();
            JCGetTrackResponse.Data trackResponseData = CollUtil.getFirst(trackResponseDataList);

            if(ObjectUtils.isEmpty(trackResponseData)) {
                getTrackResult.setErrorMsg("获取物流轨迹失败");
                return getTrackResult;
            }

            getTrackResult.setTrackingNumber(trackResponseData.getTrackingNumber());
            getTrackResult.setDestinationCountry(trackResponseData.getConsigneeCountry());

            List<JCGetTrackResponse.Data.TrackDetails> trackDetailsList = trackResponseData.getTrackDetails();
            if(ObjectUtils.isEmpty(trackDetailsList)){
                getTrackResult.setTackList(new ArrayList<>());
                return getTrackResult;
            }

            //起始时间
            JCGetTrackResponse.Data.TrackDetails startTrackDetails = CollUtil.getFirst(trackDetailsList);
            //最后一个物流时间
            JCGetTrackResponse.Data.TrackDetails overTrackDetails = CollUtil.getLast(trackDetailsList);
            //运输时间
            long transitDay = DateUtil.between(DateUtil.parseDate(startTrackDetails.getTrackDate()), DateUtil.parseDate(overTrackDetails.getTrackDate()), DateUnit.DAY);
            getTrackResult.setTransitDay((int) Math.max(transitDay,0));

            //停留时间
            long stayDay = DateUtil.between(DateUtil.parseDate(overTrackDetails.getTrackDate()), DateUtil.date(),DateUnit.DAY);
            getTrackResult.setStayDay((int) Math.max(stayDay,0));

            //
            for (JCGetTrackResponse.Data.TrackDetails tracking :trackDetailsList){
                GetTrackResult.Tack tack = new GetTrackResult.Tack();
                tack.setTime(tracking.getTrackDate());
                tack.setContent(tracking.getTrackContent());
                tack.setLocation(tracking.getTrackLocation());
                getTrackResult.getTackList().add(tack);
            }

        }catch (Exception e){
            log.error("获取物流轨迹失败",e);
            getTrackResult.setErrorMsg("获取物流轨迹失败");
        }

        return getTrackResult;
    }

    @Override
    public PrintLabelSyncResult printLabelSync(LogisticsRequest printLabelSyncRequest) {
        PrintLabelSyncResult printLabelSyncResult = new PrintLabelSyncResult();

        try {
            if(!(printLabelSyncRequest instanceof JCPrintLabelRequest)){
                printLabelSyncResult.setErrorMsg("打印面单请求参数有误");
                return printLabelSyncResult;
            }
            JCPrintLabelRequest jcPrintLabelRequest = (JCPrintLabelRequest) printLabelSyncRequest;

            HttpResponse execute = HttpUtil.createGet(jcConfig.getPrintfUrl()+ JCApiEnum.PRINT_LABEL + jcPrintLabelRequest.getOrderId()).execute();
            String location = execute.header("Location");

            byte[] bytes = HttpUtil.createGet(jcConfig.getPrintfUrl() + location).execute().bodyBytes();
            printLabelSyncResult.setBytes(bytes);
        }catch (Exception e){
            log.error("打印面单失败",e);
            printLabelSyncResult.setErrorMsg("打印面单失败");
        }
        return printLabelSyncResult;
    }

    @Override
    public LogisticsCompanyEnum getLogisticsCompanyEnum() {
        return LogisticsCompanyEnum.JC;
    }

}
